package com.gopay.bis.service.bank.impl.ebank;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.ebank.CiticB2bManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.CiticConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.citic.ebank.pay.CiticB2bMessage;
import com.gopay.common.domain.bank.citic.ebank.query.res.RowRes;
import com.gopay.common.domain.bank.citic.ebank.query.res.data.CiticB2bStreamDataRes;
import com.gopay.common.domain.bank.citic.ebank.verify.CiticB2bStreamVerify;
import com.gopay.common.domain.bank.citic.ebank.verify.RowVerify;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankInteractRemoteService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @CiticB2bBankServiceImpl.java
 * @author wanggang
 * @2013-12-12 下午1:51:26 www.gopay.com.cn Inc.All rights reserved.
 */
public class CiticB2bBankServiceImpl implements BankInteractRemoteService {

	@Resource(name = "citicB2bManager")
	private CiticB2bManager citicB2bManager;

	@Override
	public Result pay(BaseMessage base) {
		Result result = new Result(false);
		try {
			CiticB2bMessage messageB2B = new CiticB2bMessage();
			BeanUtils.copyProperties(base, messageB2B);
			messageB2B = (CiticB2bMessage) citicB2bManager.sign(messageB2B);
			base.setBankOrderId(base.getOrderId());
			result.setDefaultModel(messageB2B);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6028);
		}
		return result;
	}

	@Override
	public Result bankBack(BaseMessage base) {
		Result result = new Result(false);
		try {
			CiticB2bMessage messageB2B = new CiticB2bMessage();
			BeanUtils.copyProperties(base, messageB2B);
			CiticB2bStreamVerify stream = (CiticB2bStreamVerify) citicB2bManager.verify(messageB2B);
			RowVerify row = stream.getTran().getRows().get(0);
			stream.setBankOrderId(stream.getBizCode());
			stream.setOrderId(stream.getBizCode());
			stream.setAmount(new BigDecimal(TransUtils.amountConvert2Yuan(row.getTranAmt())));
			result.setDefaultModel(stream != null ? true : false);
			result.setModel("res", stream);
			result.setSuccess(true);			

			Map<String, String> param = new HashMap<String, String>();
			// 验签成功入账
			if (CiticConstants.ORDER_STATUS_SUCCESS.equals(row.getStt())) {					
				param.put("orderId", stream.getOrderId());
				param.put("amt", stream.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("signData", messageB2B.getSignMessage());
				param.put("isFront", String.valueOf(base.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(true);
			} else {
				// 通知后台地址该订单失败
				param.put("orderId", stream.getOrderId());
				param.put("amt", stream.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				param.put("retMsg", "验签失败");
				param.put("signData", messageB2B.getSignMessage());
				param.put("isFront", String.valueOf(base.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(false);
			}
		
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
        }
		return result;
	}

	@Override
	public Result query(BaseMessage base) {
		Result result = new Result(false);
		try {
			CiticB2bMessage messageB2B = new CiticB2bMessage();
			BeanUtils.copyProperties(base, messageB2B);
			CiticB2bStreamDataRes res = (CiticB2bStreamDataRes) citicB2bManager.query(messageB2B);
			result.setDefaultModel(res);
			result.setSuccess(true);
			if(BisPayCheckUtils.checkExternalOrderID(messageB2B.getOrderId())){
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", messageB2B.getOrderId());
				param.put("amount", messageB2B.getAmount().toString());
				if (res == null) {
					// 查询订单为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				String trnxStatus = res.getStatus(); // 该笔订单查询交易的状态
				if (!CiticConstants.SUCCESS.equals(trnxStatus)) {
					// 查询订单错误
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", res.getTxnStatus());
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				// 中信B2B查询对象
				RowRes orderDetail = (RowRes) res.getData().getRows();
				String orderStatus = orderDetail.getStt(); // 该笔订单的交易状态
				if (!StringUtils.isBlank(orderStatus)) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					// 成功
					if (orderStatus.equals(CiticConstants.ORDER_STATUS_SUCCESS)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
						param.put("returnMessage", "交易成功");
					}
					// 未确认
					else if (orderStatus.equals(CiticConstants.ORDER_STATUS_UNCONFIRM)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "银行返回交易未确认");
					}
					// 交易失败
					else if (orderStatus.equals(CiticConstants.ORDER_STATUS_FAIL)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
						param.put("returnMessage", "交易失败");
					}// 未知
					else {
						param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "银行返回交易未知");
					}
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6032);
		}
		return result;
	}

	@Override
	public Result refund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result dayend(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result queryBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

    @Override
    public Result refundBack(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result refundQuery(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

	@Override
	public Result sendBankRefund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

}
